#ifndef DOCUMENT_H
#define DOCUMENT_H

#include "appGlobals.h"
class AbstractGameObject;
namespace LevelObjects { class AbstractLevelObject; }

class Document : public QObject
{
    Q_OBJECT
	friend class AddGameObjectCommand;
public:
    typedef QList<QPointer<AbstractGameObject> > Actors;
	typedef QList<QPointer<LevelObjects::AbstractLevelObject> > Levels;
	// linear helper list (useful for view population)
	typedef QList<QPointer<AbstractGameObject> > AllGameObjects;
    explicit Document(QObject *parent = 0);

	QPointer<LevelObjects::AbstractLevelObject> createLevel(const QString& name);
    QPointer<AbstractGameObject> createActor(const QString& name);
    QPointer<AbstractGameObject> createVisualObject(const QString& name, 
                           QPointer<AbstractGameObject> parentActor);
	QPointer<AbstractGameObject> createPhysicsObject(QPointer<AbstractGameObject> parentVisualObject);

	void add(QPointer<AbstractGameObject> go);
	void remove(QPointer<AbstractGameObject> go);

	void deleteLevel(QPointer<LevelObjects::AbstractLevelObject> level);

	const Actors& actors() const;
	const AllGameObjects& allGameObjects() const;

	QPointer<LevelObjects::AbstractLevelObject> levelByGuid(const QUuid& guid);
private:
	void initGameObjectConnections(QPointer<AbstractGameObject> go);
    Actors m_actors;
	AllGameObjects m_allGameObjects;
	Levels m_levels;
signals:
    void gameObjectAdded(QPointer<AbstractGameObject> go);
    void gameObjectRemoved(QPointer<AbstractGameObject> go);
	void objectDataChanged(QPointer<AbstractGameObject> go);

	void levelCreated(QPointer<LevelObjects::AbstractLevelObject> level);
	void levelDeleted(QPointer<LevelObjects::AbstractLevelObject> level);
private slots:
	void onObjectDataChanged();
};

#endif // DOCUMENT_H
